[HVM][SVM] Change the calling convention for SVM VMMCALLs so
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 1 Aug 2006 16:28:19 +0000 (17:28 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 1 Aug 2006 16:28:19 +0000 (17:28 +0100)
that they don't conflict with the hypercall calling convention.
Signed-off-by: Steven Smith <ssmith@xensource.com>
tools/firmware/hvmloader/hvmloader.c
xen/arch/x86/hvm/svm/svm.c
xen/include/asm-x86/hvm/svm/vmmcall.h

index 702a988fab79eaddfa9ca568c2764cf604dd8eb5..4c4637dc5894e356d09ca0c2c1dc2f407385e26e 100644 (file)
@@ -31,7 +31,7 @@
 #define        ROMBIOS_PHYSICAL_ADDRESS        0x000F0000
 
 /* invoke SVM's paged realmode support */
-#define SVM_VMMCALL_RESET_TO_REALMODE  0x00000001
+#define SVM_VMMCALL_RESET_TO_REALMODE  0x80000001
 
 /*
  * C runtime start off
@@ -133,15 +133,15 @@ cirrus_check(void)
        return inb(0x3C5) == 0x12;
 }
 
-int 
-vmmcall(int edi, int esi, int edx, int ecx, int ebx)
+int
+vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
 {
         int eax;
 
         __asm__ __volatile__(
                ".byte 0x0F,0x01,0xD9"
                 : "=a" (eax)
-               : "a"(0x58454E00), /* XEN\0 key */
+               : "a"(function),
                  "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi)
        );
         return eax;
@@ -200,7 +200,7 @@ main(void)
        if (check_amd()) {
                /* AMD implies this is SVM */
                 puts("SVM go ...\n");
-                vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0);
+                vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
        } else {
                puts("Loading VMXAssist ...\n");
                memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
index 9ee9ee5bf86ab33bb5e71b31f506def0335d69c4..4490bd7f5f20a64b7d786ea58ae28c6a707212d1 100644 (file)
@@ -2349,33 +2349,41 @@ static int svm_do_vmmcall(struct vcpu *v, struct cpu_user_regs *regs)
     inst_len = __get_instruction_length(vmcb, INSTR_VMCALL, NULL);
     ASSERT(inst_len > 0);
 
-    /* VMMCALL sanity check */
-    if (vmcb->cpl > get_vmmcall_cpl(regs->edi))
+    if ( regs->eax & 0x80000000 )
     {
-        printf("VMMCALL CPL check failed\n");
-        return -1;
-    }
-
-    /* handle the request */
-    switch (regs->edi) 
-    {
-    case VMMCALL_RESET_TO_REALMODE:
-        if (svm_do_vmmcall_reset_to_realmode(v, regs)) 
+        /* VMMCALL sanity check */
+        if ( vmcb->cpl > get_vmmcall_cpl(regs->edi) )
         {
-            printf("svm_do_vmmcall_reset_to_realmode() failed\n");
+            printf("VMMCALL CPL check failed\n");
             return -1;
         }
-    
-        /* since we just reset the VMCB, return without adjusting the eip */
-        return 0;
-    case VMMCALL_DEBUG:
-        printf("DEBUG features not implemented yet\n");
-        break;
-    default:
-    break;
-    }
 
-    hvm_print_line(v, regs->eax); /* provides the current domain */
+        /* handle the request */
+        switch ( regs->eax )
+        {
+        case VMMCALL_RESET_TO_REALMODE:
+            if ( svm_do_vmmcall_reset_to_realmode(v, regs) )
+            {
+                printf("svm_do_vmmcall_reset_to_realmode() failed\n");
+                return -1;
+            }
+            /* since we just reset the VMCB, return without adjusting
+             * the eip */
+            return 0;
+
+        case VMMCALL_DEBUG:
+            printf("DEBUG features not implemented yet\n");
+            break;
+        default:
+            break;
+        }
+
+        hvm_print_line(v, regs->eax); /* provides the current domain */
+    }
+    else
+    {
+        hvm_do_hypercall(regs);
+    }
 
     __update_guest_eip(vmcb, inst_len);
     return 0;
index 41c40473f9a312bc2a2d221f6fd977fbf942b1a0..7587bab7c6ef32dc19c0823cdb6ee75fcfcf9e5f 100644 (file)
 #define __ASM_X86_HVM_SVM_VMMCALL_H__
 
 /* VMMCALL command fields */
-#define VMMCALL_CODE_CPL_MASK     0xC0000000
-#define VMMCALL_CODE_MBZ_MASK     0x3FFF0000
+#define VMMCALL_CODE_CPL_MASK     0x60000000
+#define VMMCALL_CODE_MBZ_MASK     0x1FFF0000
 #define VMMCALL_CODE_COMMAND_MASK 0x0000FFFF
 
-#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 30) | (func))
+#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 29) | (func) | 0x80000000)
 
 /* CPL=0 VMMCALL Requests */
 #define VMMCALL_RESET_TO_REALMODE   MAKE_VMMCALL_CODE(0,1)
@@ -38,7 +38,7 @@
 /* return the cpl required for the vmmcall cmd */
 static inline int get_vmmcall_cpl(int cmd)
 {
-    return (cmd & VMMCALL_CODE_CPL_MASK) >> 30;
+    return (cmd & VMMCALL_CODE_CPL_MASK) >> 29;
 }
 
 #endif /* __ASM_X86_HVM_SVM_VMMCALL_H__ */